﻿using Microsoft.VisualBasic;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Task = System.Threading.Tasks.Task;

namespace Commands
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class Command_Cursor_Number
    {
        /// <summary>
        /// Command ID.
        /// </summary>
        public const int CommandId = 0x0100;

        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("57ae64fc-bce1-4281-82e7-4b4cba38c82a");

        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly AsyncPackage package;

        /// <summary>
        /// Initializes a new instance of the <see cref="Command_Cursor_Number"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <param name="commandService">Command service to add command to, not null.</param>
        private Command_Cursor_Number(AsyncPackage package, OleMenuCommandService commandService)
        {
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

            var menuCommandID = new CommandID(CommandSet, CommandId);
            var menuItem = new MenuCommand(this.Execute, menuCommandID);
            commandService.AddCommand(menuItem);
        }

        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static Command_Cursor_Number Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the service provider from the owner package.
        /// </summary>
        private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
        {
            get
            {
                return this.package;
            }
        }

        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        public static async Task InitializeAsync(AsyncPackage package)
        {
            // Switch to the main thread - the call to AddCommand in Command_Cursor_Number's constructor requires
            // the UI thread.
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

            OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
            Instance = new Command_Cursor_Number(package, commandService);
        }

        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName);
            string title = "多光标数字";
            int v = GetCaretInfo();
            // 弹出输入对话框
            //string input = Interaction.InputBox( "请输入一个数字:","数字输入","0");
            Task<string> task = ShowInputBoxAsync("数字输入", "请输入一个数字:", "0");
            task.Wait();
            string input = task.Result;
            // 尝试转换为数字
            if (int.TryParse(input, out int number))
            {
                string text = "";
                for (int i = 0; i < v; i++)
                {
                    text += (number + i) + "";
                    if (i != v - 1)
                    {
                        text += "\n";
                    }
                }
                InsertTextAtCursors(text);
                //NativeClipboard.SetText(text);
               //VsShellUtilities.ShowMessageBox(
               // this.package,
               // "内容已添加到剪切板",
               //title,
               // OLEMSGICON.OLEMSGICON_INFO,
               // OLEMSGBUTTON.OLEMSGBUTTON_OK,
               // OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
            }
            else
            {
                VsShellUtilities.ShowMessageBox(
                this.package,
                "输入无效，请确保输入的是整数！",
                title,
                OLEMSGICON.OLEMSGICON_INFO,
                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
            }
        }

        private async Task<string> ShowInputBoxAsync(string title, string prompt, string defaultValue)
        {
            // 使用 VS 的输入框服务
            var uiShell = await ServiceProvider.GetServiceAsync<SVsUIShell, IVsUIShell>();
            uiShell.GetDialogOwnerHwnd(out IntPtr hwnd);

            IVsThreadedWaitDialogFactory factory = await ServiceProvider.GetServiceAsync<SVsThreadedWaitDialogFactory, IVsThreadedWaitDialogFactory>();

            var input = string.Empty;
            ThreadHelper.JoinableTaskFactory.Run(async () =>
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                input = Microsoft.VisualBasic.Interaction.InputBox(prompt, title, defaultValue);
            });

            return input;
        }
        /// <summary>
        /// 获取光标信息
        /// </summary>
        /// <returns></returns>
        public int GetCaretInfo()
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // 1. 获取文本管理器服务
            Task<object> task = ServiceProvider.GetServiceAsync(typeof(SVsTextManager));
            task.Wait();
            var textManager = task.Result as IVsTextManager;
            if (textManager == null)
            {
                return 0;
            }

            // 2. 获取活动文本视图
            textManager.GetActiveView(1, null, out IVsTextView vsTextView);
            if (vsTextView == null)
            {
                return 0;
            }

            // 3. 转换为 WPF 文本视图
            var userData = vsTextView as IVsUserData;
            if (userData == null)
            {
                return 0;
            }

            Guid guidViewHost = Microsoft.VisualStudio.Editor.DefGuidList.guidIWpfTextViewHost;
            if (userData.GetData(ref guidViewHost, out object viewHost) != Microsoft.VisualStudio.VSConstants.S_OK)
            {
                return 0;
            }

            IWpfTextViewHost wpfTextViewHost = viewHost as IWpfTextViewHost;
            IWpfTextView wpfTextView = wpfTextViewHost?.TextView;

            if (wpfTextView == null)
            {
                return 0;
            }

            // 4. 获取光标信息
            // 方法1: 使用 IMultiSelectionBroker (VS2019+)
            try
            {
                // 获取多选择代理
                var broker = wpfTextView.GetMultiSelectionBroker();

                // 使用 SelectedSpans 获取选择区域数量（即光标数量）
                // 注意：每个选择区域对应一个光标
                int count = broker.SelectedSpans.Count;
                return count;
            }
            catch
            {
                // 方法2: 使用 Caret.SecondaryCarets (VS2017+)
                try
                {
                    // SecondaryCarets 只包含副光标
                    int secondaryCount = 0/*wpfTextView.Caret.SecondaryCarets.Count*/;
                    // 总光标数 = 主光标(1) + 副光标数量
                    int totalCarets = 1 + secondaryCount;
                    return secondaryCount;
                }
                catch
                {
                    // 方法3: 使用 Selection.SelectedSpans (回退方案)
                    try
                    {
                        int selectionCount = wpfTextView.Selection.SelectedSpans.Count;
                        return selectionCount;
                    }
                    catch
                    {
                        // 最终回退：单光标
                        return 1;
                    }
                }
            }


            Microsoft.VisualStudio.Text.IMultiSelectionBroker multiSelectionBroker = wpfTextView.GetMultiSelectionBroker();
            int caretCount = wpfTextView.GetMultiSelectionBroker().SelectedSpans.Count;

            return caretCount;
        }


        public void InsertTextAtCursorsOld(string text)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // 获取活动文本视图
            var wpfTextView = GetActiveWpfTextView();
            if (wpfTextView == null) return;
            // 获取文本缓冲区
            ITextBuffer textBuffer = wpfTextView.TextBuffer;
            // 获取所有光标位置
            var caretPositions = GetCaretPositions(wpfTextView);
            if (caretPositions.Count == 0) return;
            caretPositions.Sort();
            caretPositions.Reverse();
            List<string> list = text.Split('\n').ToList();
            list.Reverse();

            // 使用编辑事务进行插入
            using (ITextEdit edit = textBuffer.CreateEdit())
            {
                // 倒序插入（防止位置偏移）
                for (int i = caretPositions.Count - 1; i >= 0; i--)
                {
                    int position = caretPositions[i];
                    edit.Insert(position, list[i]);
                }
                // 提交更改
                edit.Apply();
            }
        }
        public void InsertTextAtCursors(string text)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // 获取活动文本视图
            var wpfTextView = GetActiveWpfTextView();
            if (wpfTextView == null) return;

            // 获取多光标选择代理
            var multiSelectionBroker = wpfTextView.GetMultiSelectionBroker();
            if (multiSelectionBroker == null) return;

            // 获取所有选择区域（每个光标对应一个选择）
            var selections = multiSelectionBroker.AllSelections;
            if (selections.Count == 0) return;

            // 分割文本为行（每个光标插入一行）
            var lines = text.Split('\n');
            if (lines.Length != selections.Count)
            {
                // 处理行数与光标数不匹配的情况（这里简单取模循环）
                lines = Enumerable.Repeat(text, selections.Count).ToArray();
            }

            // 按位置降序排序（避免插入导致位置偏移）
            var sortedSelections = selections
                .OrderByDescending(s => s.InsertionPoint.Position)
                .ToArray();

            // 使用编辑事务进行插入
            using (ITextEdit edit = wpfTextView.TextBuffer.CreateEdit())
            {
                for (int i = 0; i < selections.Count; i++)
                {
                    var selection = selections[i];
                    int position = selection.InsertionPoint.Position;

                    // 删除已选中的文本（如果有）
                    if (!selection.IsEmpty)
                    {
                        var deleteSpan = new Span(selection.Extent.Start.Position, selection.Extent.Length);
                        edit.Delete(deleteSpan);
                    }

                    // 插入新文本
                    edit.Insert(position, lines[i]);
                }
                edit.Apply();
            }
        }
        private IWpfTextView GetActiveWpfTextView()
        {
            // 获取文本管理器服务
            Task<object> task = ServiceProvider.GetServiceAsync(typeof(SVsTextManager));
            task.Wait();
            var textManager = task.Result as IVsTextManager;
            if (textManager == null) return null;

            // 获取活动视图
            textManager.GetActiveView(1, null, out IVsTextView vsTextView);
            if (vsTextView == null) return null;

            // 转换为 WPF 文本视图
            if (!(vsTextView is IVsUserData userData)) return null;

            Guid guidViewHost = Microsoft.VisualStudio.Editor.DefGuidList.guidIWpfTextViewHost;
            if (userData.GetData(ref guidViewHost, out object viewHost) != VSConstants.S_OK)
                return null;

            return (viewHost as IWpfTextViewHost)?.TextView;
        }

        //private List<int> GetCaretPositions2(IWpfTextView wpfTextView)
        //{
        //    var positions = new List<int>();
        //    ThreadHelper.ThrowIfNotOnUIThread();
        //
        //    // 添加主光标位置
        //    positions.Add(wpfTextView.Caret.Position.BufferPosition.Position);
        //
        //    // 添加所有副光标位置
        //    try
        //    {
        //        // VS2017+ 方法
        //        foreach (var secondaryCaret in wpfTextView.Caret.SecondaryCarets)//没有这个属性SecondaryCarets 
        //        {
        //            positions.Add(secondaryCaret.Position.BufferPosition.Position);
        //        }
        //    }
        //    catch
        //    {
        //        try
        //        {
        //            // VS2019+ 方法
        //            var broker = wpfTextView.GetMultiSelectionBroker();
        //            foreach (var selection in broker.AllSelections)
        //            {
        //                if (selection.Caret != wpfTextView.Caret)//没有这个属性Caret
        //                {
        //                    positions.Add(selection.Caret.Position.BufferPosition.Position);//没有这个属性Caret
        //                }
        //            }
        //        }
        //        catch
        //        {
        //            // 回退方案：只使用主光标
        //        }
        //    }
        //
        //    return positions;
        //}
        private List<int> GetCaretPositions(IWpfTextView wpfTextView)
        {
            var positions = new List<int>();
            ThreadHelper.ThrowIfNotOnUIThread();

            // 添加主光标位置
            positions.Add(wpfTextView.Caret.Position.BufferPosition.Position);

            try
            {
                // 使用多选代理获取所有光标位置 (VS2019+)
                var broker = wpfTextView.GetMultiSelectionBroker();
                if (broker.HasMultipleSelections)
                {
                    foreach (var selection in broker.AllSelections)
                    {
                        // 跳过主光标（已添加）
                        if (selection.InsertionPoint.Equals(broker.PrimarySelection.InsertionPoint))
                            continue;

                        positions.Add(selection.InsertionPoint.Position);
                    }
                }
            }
            catch (Exception ex)
            {
                // 回退方案：尝试旧版API或仅使用主光标
    #if VS2017_COMPAT
            try
            {
                // VS2017兼容方案（如果存在）
                dynamic caret = wpfTextView.Caret;
                var secondaryCarets = caret.SecondaryCarets as IEnumerable;
                if (secondaryCarets != null)
                {
                    foreach (dynamic secCaret in secondaryCarets)
                    {
                        int pos = secCaret.Position.BufferPosition.Position;
                        if (!positions.Contains(pos))
                            positions.Add(pos);
                    }
                }
            }
            catch
            {
                // 最终回退：仅保留主光标
            }
    #endif
            }

            return positions;
        }
    }
}
